package net.kelissa.divizor.train;

import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import net.kelissa.divizor.model.CellModel;
import net.kelissa.divizor.model.DataModel;
import net.kelissa.divizor.model.DivizorModel;
import net.kelissa.divizor.model.StatDivizor;
import net.kelissa.divizor.util.MathUtil;

public class TrainerLeaf extends TrainerComponent
{

  public TrainerLeaf(DivizorModel divizor)
  {
    this.divizor = divizor;
  }

  @Override
  public void train()
  {
    DivizorModel perturbation = tryPerturbation();
    checkBest(perturbation);
  }

  private DivizorModel tryPerturbation()
  {
    DivizorModel perturbation = this.divizor.clone().perturbation();
    Map<Integer, List<DataModel>> groups = MathUtil.calcGroups(perturbation);
    for (Entry<Integer, CellModel> entry : perturbation.getCells().entrySet())
    {
      CellModel cell = entry.getValue();
      cell.recalcDivizor(groups.get(cell.getId()), perturbation.getWeights());
    }
    return perturbation;
  }

  private void checkBest(DivizorModel perturbation)
  {
    StatDivizor statDivizor = MathUtil.calcStat(this.divizor);
    StatDivizor tmpStat = MathUtil.calcStat(perturbation);
    if (tmpStat.getFitness() >= statDivizor.getFitness())
    {
      if (tmpStat.getFitness() > statDivizor.getFitness())
      {
        this.age = 0;
      }
      statDivizor = tmpStat;
      this.divizor = perturbation;
    }
    this.age += 1;
  }

}
